﻿using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
using AudiPyme.BLL;
using System.IO;
using System.Data;
using AudiPyme.DAL;
using System.Web.UI.HtmlControls;

namespace AudiPyme.UI
{
    public partial class InformesGestionar : System.Web.UI.Page
    {
        //Estructura para formatear la información de los informes a la tabla de la interfaz
        public struct InformeTabla
        {
            int idInforme;
            DateTime fecha;
            String tipoInforme;

            public String TipoInforme
            {
                get { return tipoInforme; }
                set { tipoInforme = value; }
            }

            public int IdInforme
            {
                get { return idInforme; }
                set { idInforme = value; }
            }

            public DateTime Fecha
            {
                get { return fecha; }
                set { fecha = value; }
            }

            public InformeTabla(int IdInforme, DateTime Fecha, String TipoInforme)
            {
                idInforme = IdInforme;
                fecha = Fecha;
                tipoInforme = TipoInforme;
            }
        }


        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                int IdEmpresa = DatosEmpresa();
                if (IdEmpresa != -1)
                {
                    //Creamos la estructura para almacenar los elementos elegidos en el gridview
                    //Número de controles seleccionados actualmente
                    int nControlesOn = 0;
                    int numInf = InformesFactory.NumeroInformesEmpresa(IdEmpresa);
                    GeneraOpciones(IdEmpresa, numInf);
                    //Numero de controles que hay actualmente en la BD
                    ModeloContainer agenteBD = new ModeloContainer();
                    //Máximo de Elementos que vamos a manejar en el Informe
                    int max = 1000;
                    //Inicializamos la estructura que va a almacenar los estados de los informes seleccionados
                    List<InformeCheck> CheckList = new List<InformeCheck>(max);
                    //Guardamos en variables de sesión
                    Session["CheckList"] = CheckList;
                    Session["nControlesOn"] = nControlesOn;
                    String OpcionFiltro = RblFiltro.SelectedValue;
                    String TextoBuscar = TxtFiltro.Text;
                    LlenaGridView(OpcionFiltro, TextoBuscar);
                }
                else
                {
                    MuestraMensaje("No se pudo recoger la empresa");
                }
            }
        }

        private void GeneraOpciones(int IdEmpresa, int NumeroInformesEmpresa)
        {
            try
            {
                //Se recoge el número de activos que tiene la empresa
                int NumActivosEmp = ActivosEmpresaFactory.NumeroTotalesActivosEmpresa(IdEmpresa);
                //Si la empresa tiene activos
                if (NumActivosEmp != 0)
                {
                    int NumRelTipActAmenCrit = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.NumRelacTipAmenCritEmpresa(IdEmpresa);
                    int NumRelTipActVuln = InstanciaTiposActivosVulnerabilidadesFactory.NumRelacTipActVuln(IdEmpresa);
                    //Si la empresa tiene activos y relaciones puede generar un informe
                    if (NumRelTipActAmenCrit != 0 && NumRelTipActVuln != 0)
                    {
                        HtmlGenericControl opc2 = new HtmlGenericControl("li");
                        ListaOpciones.Controls.Add(opc2);
                        HtmlGenericControl anchor2 = new HtmlGenericControl("a");
                        anchor2.Attributes.Add("href", "InformesPrincipal.aspx");
                        anchor2.InnerText = "Informes Principal";
                        opc2.Controls.Add(anchor2);
                    }
                }
                int NumInformesEmp = EmpresaInformeFactory.NumeroInformesEmpresa(IdEmpresa);
                if (NumInformesEmp != 0)
                {
                    HtmlGenericControl opc2 = new HtmlGenericControl("li");
                    ListaOpciones.Controls.Add(opc2);
                    HtmlGenericControl anchor2 = new HtmlGenericControl("a");
                    anchor2.Attributes.Add("href", "InformesConsultar.aspx");
                    anchor2.InnerText = "Consultar Informes";
                    opc2.Controls.Add(anchor2);
                }
            }
            catch (System.Web.HttpException e1)
            {
                e1.ToString();
                MuestraMensaje("Error al generar las opciones de navegación de la página");
            }
        }

        //Método que se ejecuta al evento de cliquear uno de los checkbox de cualquier elemento de la tabla
        protected void CheckBox_Changued(Object sender, EventArgs e)
        {
            try
            {
                //Recuperamos las variables de sesión
                //Recogemos el valor de los elementos seleccionados en las otras paginas del GridView
                //con la variable de sesión nControlesOn
                int nControlesOn = (int)Session["nControlesOn"];
                List<InformeCheck> CheckList = (List<InformeCheck>)Session["Checklist"];
                //Recorremos la página que el gridview muestra
                foreach (GridViewRow row in GVVulnerab.Rows)
                {
                    //Recogemos el control CheckBox de cada fila del gridview
                    CheckBox Chk = (CheckBox)row.FindControl("CheckBox1");
                    //Recogemos el Id de Informe de cada fila
                    int IdInforme;
                    int.TryParse(GVVulnerab.Rows[row.RowIndex].Cells[0].Text, out IdInforme);
                    //Si es la primera vez que se elige este elemento, aumentamos el contador
                    //y marcamos que ese elemento ya está elegido
                    if (Chk.Checked == true && !EstaRelacion(CheckList, IdInforme))
                    {
                        if (nControlesOn == 0)
                        {
                            BtnEliminar.Enabled = true;
                        }
                        CheckList.Add(new InformeCheck(IdInforme, true));
                        nControlesOn++;
                    }
                    //Sino marcamos que el informe no está elegido y actualizamos estructuras
                    else if (Chk.Checked == false && EstaRelacion(CheckList, IdInforme))
                    {
                        //Eliminamos las ocurrencias guardadas anteriormente de la relación
                        for (int i = 0; i < CheckList.Count(); i++)
                        {
                            if (CheckList[i].IdInforme == IdInforme)
                            {
                                CheckList.RemoveAt(i);
                            }
                        }

                        nControlesOn--;
                        if (nControlesOn == 0)
                        {
                            BtnEliminar.Enabled = false;
                        }
                    }
                }
                //Si estamos en la opción de Relaciones Seleccionadas, actualizamos el gridview
                String OpcionFiltro = RblFiltro.SelectedValue;
                if (OpcionFiltro.Equals("RelacSelec"))
                {
                    GridViewRelacionesSeleccionadas();
                }
                //Actualizamos el número de controles elegidos en el label
                LblControl.Text = nControlesOn.ToString();
                //Guardamos en la variable de sesión
                Session["CheckList"] = CheckList;
                Session["nControlesOn"] = nControlesOn;
            }
            catch (Exception e1)
            {
                MuestraMensaje("Error al hacer click en el elemento de la tabla");
                e1.ToString();
            }
        }


        protected void GVVulnerab_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            try
            {
                //Recogemos el array tipado con el valor de los elementos que han sido elegidos
                List<InformeCheck> CheckList = (List<InformeCheck>)Session["Checklist"];
                //Recorremos el Gridview antes de cambiar de página
                foreach (GridViewRow row in GVVulnerab.Rows)
                {
                    //Recogemos el control CheckBox de cada fila
                    CheckBox Chk = (CheckBox)row.FindControl("CheckBox1");
                    //Si está seleccionado
                    if (Chk.Checked == true)
                    {
                        //Recogemos el IdInforme de la fila
                        int IdInforme;
                        int.TryParse(GVVulnerab.Rows[row.RowIndex].Cells[0].Text, out IdInforme);
                    }
                    //Si no está seleccionado
                    if (Chk.Checked == false)
                    {
                        //Recogemos el IdInforme de la fila
                        int IdInforme;
                        int.TryParse(GVVulnerab.Rows[row.RowIndex].Cells[0].Text, out IdInforme);
                        //Actualizamos el valor de contador
                        if (EstaRelacion(CheckList, IdInforme))
                        {
                            //Creamos una instancia y lo eliminamos de la lista
                            int indice = IndiceRelacion(CheckList, IdInforme);
                            CheckList.RemoveAt(indice);
                        }
                    }
                }
                //Actualizamos la variable de sesión
                this.GVVulnerab.PageIndex = e.NewPageIndex;
                Session["CheckList"] = CheckList;
                String OpcionFiltro = RblFiltro.SelectedValue;
                if (OpcionFiltro.Equals("RelacSelec"))
                {
                    GridViewRelacionesSeleccionadas();
                }
                else
                {
                    OpcionFiltro = RblFiltro.SelectedValue;
                    String TextoBuscar = TxtFiltro.Text;
                    LlenaGridView(OpcionFiltro, TextoBuscar);
                    ActualizaCheckListTabla();
                }
            }
            catch (Exception e1)
            {
                e1.ToString();
                MuestraMensaje("Error al actualizar la tabla con los elementos seleccionados");
            }
        }

        private void GridViewRelacionesSeleccionadas()
        {
            try
            {
                ModeloContainer agenteBD = new ModeloContainer();
                //Recogemos el array tipado con el valor de los elementos que han sido elegidos
                List<InformeCheck> CheckList = (List<InformeCheck>)Session["Checklist"];
                List<InformeTabla> LRelacionesSelec = new List<InformeTabla>();
                //Cargamos el valor de los elementos que estuvieran seleccionados anteriormente
                for (int i = 0; i < CheckList.Count(); i++)
                {
                    if (CheckList[i].Check == true)
                    {
                        InformeTabla nuevaFila = new InformeTabla();
                        nuevaFila.IdInforme = CheckList[i].IdInforme;
                        nuevaFila.Fecha = InformesFactory.FechaInforme(CheckList[i].IdInforme);
                        nuevaFila.TipoInforme = InformesFactory.TipoInforme(CheckList[i].IdInforme);
                        LRelacionesSelec.Add(nuevaFila);
                    }
                }
                GVVulnerab.DataSource = LRelacionesSelec;
                DataBind();
                ActualizaCheckListTabla();
            }
            catch (Exception e1)
            {
                e1.ToString();
                MuestraMensaje("Error al actualizar la tabla con los elementos seleccionados");
            }
        }

        //Método que indica si un elemento está seleccionado y por tanto, en el Checklist
        private bool EstaRelacion(List<InformeCheck> CheckList, int IdInforme)
        {
            for (int i = 0; i < CheckList.Count(); i++)
            {
                if (CheckList[i].IdInforme == IdInforme)
                {
                    return true;
                }
            }
            return false;
        }

        //Devuelve el índice de un elemento seleccionado
        private int IndiceRelacion(List<InformeCheck> CheckList, int IdInforme)
        {
            for (int i = 0; i < CheckList.Count(); i++)
            {
                if (CheckList[i].IdInforme == IdInforme)
                {
                    return i;
                }
            }
            return -1;
        }


        protected void BtnEliminar_Click(object sender, EventArgs e)
        {
            List<InformeCheck> CheckList = (List<InformeCheck>)Session["Checklist"];
            List<int> LInformes = new List<int>();
            try
            {
                //Se eliminan los informes seleccionados así como toda la información disponible de ellos en la BD
                foreach (InformeCheck Inf in CheckList)
                {
                    LInformes.Add(Inf.IdInforme);
                }
                InformesFactory.EliminaTotalInformes(LInformes);
                MuestraMensajeRedirige("Informes y su conocimiento asociado eliminados correctamente");

            }
            catch (Exception e1)
            {
                e1.ToString();
                MuestraMensaje("Error al eliminar los informes");
            }
            finally
            {
                //Recoge datos y llena el gridview con los mismos, así como actualiza los valores seleccionados
                String OpcionFiltro = RblFiltro.SelectedValue;
                String TextoBuscar = TxtFiltro.Text;
                LlenaGridView(OpcionFiltro, TextoBuscar);
                ActualizaCheckListTabla();
            }
        }

        private void MuestraMensajeRedirige(string Mensaje)
        {
            StringBuilder SB = new StringBuilder();
            SB.Append("alert('");
            SB.Append(Mensaje.Replace("\n", "\\n").Replace("\r", "").Replace("'", "\\'"));
            SB.Append("');");
            SB.Append("var vers = navigator.appVersion;if(vers.indexOf('MSIE 7.0') != -1) { window.location='InformesGestionar.aspx';} else{ window.location='InformesGestionar.aspx'; }");
            ScriptManager.RegisterStartupScript(this, this.GetType(), "Success", SB.ToString(), true);
        }

        //Evento click de botón buscar
        protected void BtnBuscar_Click(object sender, EventArgs e)
        {
            //Recoge datos y llena el gridview con los mismos, así como actualiza los valores seleccionados
            String OpcionFiltro = RblFiltro.SelectedValue;
            String TextoBuscar = TxtFiltro.Text;
            LlenaGridView(OpcionFiltro, TextoBuscar);
            ActualizaCheckListTabla();
        }

        //Método que sirve para actualizar los informes seleccionados en cada evento
        private void ActualizaCheckListTabla()
        {
            try
            {
                //Recogemos el array tipado con el valor de los elementos que han sido elegidos
                List<InformeCheck> CheckList = (List<InformeCheck>)Session["Checklist"];
                //Cargamos el valor de los elementos que estuvieran seleccionados anteriormente
                for (int i = 0; i < CheckList.Count(); i++)
                {
                    foreach (GridViewRow row in GVVulnerab.Rows)
                    {
                        int IdInforme;
                        int.TryParse(GVVulnerab.Rows[row.RowIndex].Cells[0].Text, out IdInforme);
                        if (IdInforme == CheckList[i].IdInforme)
                        {
                            CheckBox Chk = (CheckBox)row.FindControl("CheckBox1");
                            if (CheckList[i].Check)
                            {
                                Chk.Checked = true;
                            }
                            else
                            {
                                Chk.Checked = false;
                            }
                        }
                    }
                }
            }
            catch (Exception e1)
            {
                e1.ToString();
                MuestraMensaje("Error al mostrar los elementos seleccionados");
            }

        }

        private void MuestraMensaje(string Mensaje)
        {
            StringBuilder SB = new StringBuilder();
            SB.Append("alert('");
            SB.Append(Mensaje.Replace("\n", "\\n").Replace("\r", "").Replace("'", "\\'"));
            SB.Append("');");
            ScriptManager.RegisterStartupScript(this, this.GetType(), "Success", SB.ToString(), true);
        }

        private void LlenaGridView(String OpcionFiltro, String TextoBuscar)
        {
            try
            {
                ModeloContainer agenteBD = new ModeloContainer();
                OpcionFiltro = RblFiltro.SelectedValue;
                TextoBuscar = TxtFiltro.Text;
                int IdEmpresa = DatosEmpresa();
                if (IdEmpresa != -1)
                {
                    //Sacamos los informes que tiene una empresa
                    List<Informes> LInformes = InformesFactory.InformesEmpresa(IdEmpresa);
                    //Si no se ha introducido texto de búsqueda, sacamos todas los informes disponibles
                    if (TextoBuscar.Equals(""))
                    {
                        GVVulnerab.DataSource = LInformes;
                        DataBind();
                    }
                    else
                    {
                        //Opción Fecha
                        if (OpcionFiltro.Equals("Fecha"))
                        {
                            int dia = 0; int mes = 0; int anio = 0;
                            //Comprobamos que el texto introducido es una fecha
                            if (EsFecha(TextoBuscar))
                            {
                                dia = int.Parse(TextoBuscar.Substring(0, 2));
                                mes = int.Parse(TextoBuscar.Substring(3, 2));
                                anio = int.Parse(TextoBuscar.Substring(6, 4));
                                //Recogemos los Informes con la fecha del textbox
                                LInformes = InformesFactory.InformesPorFecha(IdEmpresa, dia, mes, anio);
                            }
                            else
                            {
                                MuestraMensaje("No se especifico una fecha válida. Formato de fecha: dd-mm-aaaa");
                            }

                        }
                        else
                        {
                            MuestraMensaje("No se recogio la opcion de Filtro elegida");
                        }
                        if (LInformes.Count() == 0)
                        {
                            MuestraMensaje("No se encontraron Informes con fecha: " + TextoBuscar);
                        }
                        else
                        {
                            GVVulnerab.DataSource = LInformes;
                            DataBind();
                        }
                    }
                }
            }
            catch (Exception e1)
            {
                e1.ToString();
                MuestraMensaje("Error al actualizar los valores de la tabla");
            }
        }

        //Determina si un string tiene el formato de una fecha
        private bool EsFecha(String SFecha)
        {
            try
            {
                CultureInfo proveedor = CultureInfo.InvariantCulture;
                DateTime.ParseExact(SFecha, "dd-MM-yyyy", proveedor);
                return true;
            }
            catch (FormatException)
            {
                return false;
            }
        }

        private int DatosEmpresa()
        {
            try
            {
                int IdEmpresa = -1;
                String nombreUsuario = (String)Session["nombreUsuario"];
                IdEmpresa = UsuariosFactory.EmpresaUsuario(nombreUsuario);
                if (IdEmpresa == 0)
                {
                    MuestraMensaje("El usuario " + nombreUsuario + " no esta asociado a una empresa");
                    return -1;
                }
                else
                {
                    return IdEmpresa;
                }
            }
            catch (Exception e1)
            {
                e1.ToString();
                Session.Abandon();
                MuestraMensajeRedirige("Error al recoger la variable de sesión. La aplicación se cerrará por motivos de seguridad", "InicioSesion");
                return -1;
            }
        }

        //Evento para cuando cambia el RadioButton
        protected void RblFiltro_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (RblFiltro.SelectedValue.Equals("RelacSelec"))
            {
                TxtFiltro.Visible = false;
                BtnBuscar.Visible = false;
                GridViewRelacionesSeleccionadas();
            }
            else
            {
                TxtFiltro.Visible = true;
                BtnBuscar.Visible = true;
                //Limpiamos el TextBox ya que venimos de otra opción
                TxtFiltro.Text = "";
                String OpcionFiltro = RblFiltro.SelectedValue;
                String TextoBuscar = TxtFiltro.Text;
                LlenaGridView(OpcionFiltro, TextoBuscar);
                ActualizaCheckListTabla();
            }
        }


        private void MuestraMensajeRedirige(string Mensaje, string Pagina)
        {
            StringBuilder SB = new StringBuilder();
            SB.Append("alert('");
            SB.Append(Mensaje.Replace("\n", "\\n").Replace("\r", "").Replace("'", "\\'"));
            SB.Append("');");
            SB.Append("var vers = navigator.appVersion;if(vers.indexOf('MSIE 7.0') != -1) { window.location='" + Pagina + ".aspx';} else{ window.location='" + Pagina + ".aspx'; }");
            ScriptManager.RegisterStartupScript(this, this.GetType(), "Success", SB.ToString(), true);
        }

        //Estructura que sirve para recoger los informes seleccionados en la interfaz
        private struct InformeCheck
        {
            int idInforme;
            bool check;

            public int IdInforme
            {
                get { return idInforme; }
                set { idInforme = value; }
            }


            public bool Check
            {
                get { return check; }
                set { check = value; }
            }

            public InformeCheck(int IdInforme, bool Check)
            {
                idInforme = IdInforme;
                check = Check;
            }
        }
    }
}